#!/bin/bash

DIR_COPY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
DIR_JSON="${DIR_COPY}/../json"
DIR_RESULT="${DIR_COPY}/../result"
DIR_TOOLS="${DIR_COPY}/../tools"

PATH_SETTING_CONFIG="${DIR_JSON}/setting_config4.json"
PATH_DESIGN="${DIR_JSON}/design1"
PATH_CPP="Example.cpp"
PATH_WAFER="${DIR_COPY}/wafer.sh"
PATH_RUN="${DIR_TOOLS}/design_run"
PATH_COMPILE_TIME="${DIR_RESULT}/compiletime.log"
PATH_RUN_TIME="${DIR_RESULT}/runtime2.log"  #因为课题五说runtime.log和课题四冲突了
PATH_MERGE="${DIR_COPY}/jsonMerge.py"
PATH_PERFORMANCE_ANALYSIS="${DIR_COPY}/performanceAnalysis.py"

params=""

check_file() {
    local file_path="$1"
    local description="$2"
    if [ ! -f "$file_path" ]; then
        echo "error: The $description file is not exist. Please check the path: $file_path."
        exit 1
    fi
}

check_dependencies() {
    if ! command -v jq &> /dev/null; then
        echo "error: You need install <jq> tool."
        exit 1
    fi

    if ! command -v python3 &> /dev/null; then
        echo "error: You need install <python3> tool."
        exit 1
    fi
}

#1 修改：根据 setting_config.json 修改 desgin1x.json
process_json() {
    local num_group=$(jq -r '.num_group' "$PATH_SETTING_CONFIG")
    PATH_DESIGN="${PATH_DESIGN}${num_group}.json"
    check_file $PATH_DESIGN "DESIGN"
}

#2 修改：根据 setting_config.json 修改 example.cpp
process_cppexample() {
    local type_crypto=$(jq -r '.type_crypto' "$PATH_SETTING_CONFIG")
    PATH_CPP="${DIR_COPY}/${type_crypto}${PATH_CPP}"
    check_file $PATH_CPP "CPP"

    local num_input=$(jq -r '.num_input' "$PATH_SETTING_CONFIG")
    local len_plaintext=$(jq -r '.len_plainText' "$PATH_SETTING_CONFIG")

    local tmp_file=$(mktemp)
    if [[ "${type_crypto,,}" != "aes" ]]; then
        local data_input=$(jq -r '.data_input | map("'"'"'\(.)'"'"'") | join(", ")' "$PATH_SETTING_CONFIG")
        local data_target=$(jq -r '.data_target | join(", ")' "$PATH_SETTING_CONFIG")
        {
            sed -n "1,/^uint8_t candidates/p" "$PATH_CPP" | \
                sed "$ s/^uint8_t candidates.*//" | \
                sed "/^#define MSG_NUM/c\#define MSG_NUM $num_input" | \
                sed "/^#define MSG_LEN/c\#define MSG_LEN $len_plaintext"
            echo "uint8_t candidates[TOTAL_MSG_SIZE] = {$data_input};"
            echo "uint8_t target[HASH_SIZE] = {$data_target};"
            sed -n '/^uint8_t result/,$p' "$PATH_CPP"
        } > "$tmp_file"
    else
        local data_input=$(jq -r '.data_input | join(", ")' "$PATH_SETTING_CONFIG")
        local data_target=$(jq -r '.data_target | map("'"'"'\(.)'"'"'") | join(", ")' "$PATH_SETTING_CONFIG")
        {
            sed -n "1,/^uint8_t exampleInput/p" "$PATH_CPP" | \
                sed "$ s/^uint8_t exampleInput.*//" | \
                sed "/^#define MSG_CNT/c\#define MSG_CNT $num_input"
            echo "uint8_t exampleInput[INPUT_SIZE] = {$data_input};"
            echo "uint8_t exampleKey[KEY_SIZE] = {$data_target};"
            sed -n '/^MemRef<unsigned char, 1> input/,$p' "$PATH_CPP"
        } > "$tmp_file"
    fi

    mv "$tmp_file" "$PATH_CPP"
}

#3 配置：根据 setting_config.json 配置 all params
process_params() {
    if [[ $(jq -r '.printschedule' "$PATH_SETTING_CONFIG") == "true" ]]; then
        params+="-printschedule "
    fi
    if [[ $(jq -r '.openssl' "$PATH_SETTING_CONFIG") == "true" ]]; then
        params+="-openssl "
    fi
}

#4 编译：wafer.sh -> compiletime.log + (.out|.ptx|.v|.xml)
process_compile() {
    check_file $PATH_WAFER "WAFER"
    local temp_log=$(mktemp)
    {   
        ${PATH_WAFER} -j ${PATH_DESIGN} -i ${PATH_CPP} -o wafer_run_exe ${params}
    } | tee -a $temp_log
    mv $temp_log $PATH_COMPILE_TIME
}

#5 运行: desgin_run -> runtime2.log + group_x.json
process_run() {
    check_file $PATH_RUN "RUN"
    local temp_log=$(mktemp)
    {   
        ${PATH_RUN}
    } | tee -a $temp_log
    mv $temp_log $PATH_RUN_TIME
}

#6 合并异构结果: jsonMerge.py + group_x.json -> group_merge.json
process_merge() {
    check_file $PATH_MERGE "MERGE"
    python3 $PATH_MERGE
}

#7 解析性能参数: performanceAnalysis.py + runtime2.log -> performance.json
process_log() {
    check_file $PATH_PERFORMANCE_ANALYSIS "PERFORMANCE"
    python3 $PATH_PERFORMANCE_ANALYSIS
}

main() {
    echo "=== begin setting ==="
    check_file $PATH_SETTING_CONFIG "CONFIG"
    check_dependencies
    process_json
    process_cppexample
    process_params
    process_compile
    process_run
    process_merge
    process_log
    echo "=== setting over ==="
}

main